import { AxiosResponse } from 'axios';
import { deepMerge, setObjToUrlParams } from '..';
import { isString } from '../is';
import { VAxios } from './axios';
import { formatRequestDate, joinTimestamp } from './helper';
import { ContentTypeEnum, RequestEnum } from '../../enums/httpEnum';
import { AxiosTransform, CreateAxiosOptions } from './types';
import { useGlobSetting } from '@/hooks/setting';

const globSetting = useGlobSetting();

const transform: AxiosTransform = {
	beforeRequestHook: (config, options) => {
		const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;

		if (joinPrefix) {
			config.url = `${urlPrefix}${config.url}`;
		}

		if (apiUrl && isString(apiUrl)) {
			config.url = `${apiUrl}${config.url}`;
		}
		const params = config.params || {};
		// 'PUT', 'POST', and 'PATCH'
		const data = config.data || false;
		if (config.method?.toUpperCase() === RequestEnum.GET) {
			if (!isString(params)) {
				// 给 get 请求加上时间戳参数，避免从缓存中拿数据。
				config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
			} else {
				config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
				config.params = undefined;
			}
		} else {
			if (!isString(params)) {
				formatDate && formatRequestDate(params);
				if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
					config.data = data;
					config.params = params;
				} else {
					// 非GET请求如果没有提供data，则将params视为data
					config.data = params;
					config.params = undefined;
				}
				if (joinParamsToUrl) {
					config.url = setObjToUrlParams(config.url as string, Object.assign({}, config.params, config.data));
				}
			} else {
				// 兼容restful风格
				config.url = config.url + params;
				config.params = undefined;
			}
		}
		return config;
	},
	/**
	 * @description: 响应拦截器处理
	 */
	responseInterceptors: (res: AxiosResponse<any>) => {
		return res;
	},
};

export function createAxios(opts?: Partial<CreateAxiosOptions>) {
	return new VAxios(
		deepMerge(
			{
				// authentication schemes，e.g: Bearer
				// authenticationScheme: 'Bearer',
				authenticationScheme: '',
				timeout: 10 * 1000,
				// 基础接口地址
				baseURL: '/',

				headers: { 'Content-Type': ContentTypeEnum.JSON },
				// 如果是form-data格式
				// headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
				// 数据处理方式
				transform,
				// 配置项，下面的选项都可以在独立的接口请求中覆盖
				// ${baseURL}${apiUrl}${joinPrefix ? urlPrefix : ''}${config.url}
				requestOptions: {
					// 默认将prefix 添加到url
					joinPrefix: true,
					// 是否返回原生响应头 比如：需要获取响应头时使用该属性
					isReturnNativeResponse: false,
					// 需要对返回数据进行处理
					isTransformResponse: true,
					// post请求的时候添加参数到url
					joinParamsToUrl: false,
					// 格式化提交参数时间
					formatDate: true,
					// 消息提示类型
					errorMessageMode: 'message',
					// 接口地址
					apiUrl: globSetting.apiUrl,
					// 接口前缀
					urlPrefix: globSetting.urlPrefix,
					//  是否加入时间戳
					joinTime: true,
					// 忽略重复请求
					ignoreCancelToken: true,
					// 是否携带token
					withToken: true,
					// 是否是第三方api
					apiType: '',
				},
			},
			opts || {},
		),
	);
}
